package geometric3D;

import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.List;

public class XYRectangle extends Rectangle {

	public XYRectangle(Point positionPoint ,int xSize, int ySize, boolean isPositiveFaced) {
		this.position = positionPoint;
		this.width = xSize;
		this.height = ySize;
		this.isPositiveFaced = isPositiveFaced;

	}
	
	public XYRectangle() {
		super();

	}

	public XYRectangle(int width, int height, boolean isPositiveFaced) {
		super(width, height, isPositiveFaced);

	}
	
	public xLineSegment getXLineSegment(boolean isPositiveFaced){
		if(isPositiveFaced){
			return new xLineSegment(
					new Point(position.getX(), position.getY()+getYSize(), position.getZ()), 
					new Point(position.getX()+getXSize(), position.getY()+getYSize(), position.getZ()));
		}else{
			return new xLineSegment(
					new Point(position.getX(), position.getY(), position.getZ()), 
					new Point(position.getX()+getXSize(), position.getY(), position.getZ()));
		}
		
	}
	
	public yLineSegment getYLineSegment(boolean isPositiveFaced){
		if(isPositiveFaced){
			return new yLineSegment(
						new Point(position.getX()+getXSize(), position.getY(), position.getZ()), 
						new Point(position.getX()+getXSize(), position.getY()+getYSize(), position.getZ()));
			
		}else{
			return new yLineSegment(
					new Point(position.getX(), position.getY(), position.getZ()), 
					new Point(position.getX(), position.getY()+getYSize(), position.getZ()));
		}
	}
	

	public int getXSize(){
		return this.width;
	}
	public void setXSize(int xSize){
		this.width = xSize;
	}
	public int getYSize(){
		return this.height;
	}
	public void setYSize(int ySize){
		this.height= ySize;
	}
	
	public int getMaxX(){
		return  this.position.getX() + getXSize();
	}
	public int getMaxY(){
		return  this.position.getY() + getYSize();
	}
	public int getMinX(){
		return this.position.getX();
	}
	public int getMinY(){
		return this.position.getY();
	}
	@Override
	public String toString() {
		return "XYRectangle [position=" + position + ", width=" + width
				+ ", height=" + height + ", isPositiveFaced=" + isPositiveFaced
				+ ", getArea()=" + getArea() + "]\n";
	}

	@Override
	public Rectangle2D toRectangle2D() {

		return new Rectangle2D.Double(position.getX(), position.getY(), getXSize(), getYSize());
	}
	
	public XYRectangle getOverlaped(XYRectangle xyRectangle){
		Rectangle2D thisRectangle2D = this.toRectangle2D();
		Rectangle2D xyRectangle2D = xyRectangle.toRectangle2D();
		Rectangle2D intersection = thisRectangle2D.createIntersection(xyRectangle2D);
		Point intersectionPosition = new Point((int)intersection.getX(), 
				(int)intersection.getY(), this.position.getZ());
		
		
		return new XYRectangle(intersectionPosition, (int)intersection.getWidth(), (int)intersection.getHeight(), isPositiveFaced);
		
	}
	
	public List<XYRectangle> getLeftOver(XYRectangle xyRectangle,Rectangle2DRelation relation){
		List<XYRectangle> result = new ArrayList<XYRectangle>();
		if(relation ==  Rectangle2DRelation.OUTSIDE
				|| relation ==  Rectangle2DRelation.TOUCHING){
			result.add(this);
		}else if(relation ==  Rectangle2DRelation.INSIDE){
		}else if(relation ==  Rectangle2DRelation.CONTAIN){
			result.addAll(getLeftOverInside(xyRectangle));
		}else if(relation == Rectangle2DRelation.ONEINSIDE){
			result.addAll(getLeftOverOnePoint(xyRectangle));
		}else if(relation == Rectangle2DRelation.TWOINSIDE){
			result.addAll(getLeftOverTwoPoint(xyRectangle));
		}else if(relation == Rectangle2DRelation.ZEROINSIDE){
			result.addAll(getLeftOverZeroPoint(xyRectangle));
		}
		return result;
	}
	
	
	
	
	
	public List<XYRectangle> getLeftOverInside(XYRectangle xyRectangle){
		List<XYRectangle> result = new ArrayList<XYRectangle>();
		int leftOverX =-1;
		int leftOverY =-1;
		int leftOverPositionX =-1;
		int leftOverPositionY =-1;
		
		leftOverX = xyRectangle.getMinX() - this.getMinX();
		leftOverY = this.getYSize();
		leftOverPositionX = this.getMinX();
		leftOverPositionY = this.getMinY();
		
		if(leftOverX>0 && leftOverY>0){
			result.add(new XYRectangle(new Point(leftOverPositionX, leftOverPositionY, this.position.getZ()),
					leftOverX, leftOverY, this.isPositiveFaced));
			
		}
		
		leftOverX = xyRectangle.getXSize();
		leftOverY = xyRectangle.getMinY() - this.getMinY();
		leftOverPositionX = xyRectangle.getMinX();
		leftOverPositionY = this.getMinY();
		
		if(leftOverX>0 && leftOverY>0){
			result.add(new XYRectangle(new Point(leftOverPositionX, leftOverPositionY, this.position.getZ()),
					leftOverX, leftOverY, this.isPositiveFaced));
			
		}
		
		leftOverX = xyRectangle.getXSize();
		leftOverY = this.getMaxY() - xyRectangle.getMaxY();
		leftOverPositionX = xyRectangle.getMinX();
		leftOverPositionY = xyRectangle.getMaxY();
		
		if(leftOverX>0 && leftOverY>0){
			result.add(new XYRectangle(new Point(leftOverPositionX, leftOverPositionY, this.position.getZ()),
					leftOverX, leftOverY, this.isPositiveFaced));
			
		}
		
		leftOverX = this.getMaxX() - xyRectangle.getMaxX();
		leftOverY = this.getYSize();
		leftOverPositionX = xyRectangle.getMaxX();
		leftOverPositionY = this.getMinY();
		
		if(leftOverX>0 && leftOverY>0){
			result.add(new XYRectangle(new Point(leftOverPositionX, leftOverPositionY, this.position.getZ()),
					leftOverX, leftOverY, this.isPositiveFaced));
			
		}
		
		
		
		return result;
	}
//	public Rectangle2DRelation findRelation(XYRectangle xyRectangle){
//		Rectangle2D this2D = this.toRectangle2D();
//		Rectangle2D xyRectangle2D = xyRectangle.toRectangle2D();
//		
//		if(xyRectangle2D.contains(this2D))return Rectangle2DRelation.INSIDE;
//		if(this2D.contains(xyRectangle2D)) return Rectangle2DRelation.CONTAIN;
//		if((this.getMinX() == xyRectangle.getMaxX()
//				|| this.getMaxX() == xyRectangle.getMinX())
//				&& (xyRectangle.getMinY() <= this.getMaxY()  
//						&& xyRectangle.getMinY() >= this.getMinY() 
//					||xyRectangle.getMaxY() <= this.getMaxY()  
//						&& xyRectangle.getMaxY() >= this.getMinY())){
//			return Rectangle2DRelation.TOUCHING;
//		}else if((this.getMinY() == xyRectangle.getMaxY()
//				|| this.getMaxY() == xyRectangle.getMinY())
//				&& ((xyRectangle.getMinX() <= this.getMaxX()  
//						&& xyRectangle.getMinX() >= this.getMinX()) 
//					||(xyRectangle.getMaxX() <= this.getMaxX()  
//						&& xyRectangle.getMaxX() >= this.getMinX()))){
//			return Rectangle2DRelation.TOUCHING;
//		}else if(this2D.intersects(xyRectangle2D)){
//			int pointContain =0 ;
////			System.out.println(this.getPoint2D());
////			System.out.println(xyRectangle.getPoint2D());
//			for(Point2D p2D : xyRectangle.getPoint2D()){
//				if(this2D.contains(p2D)){
////					System.out.println(p2D);
//					pointContain++;
//				}
//				
//			}
//			if(pointContain==0){
//				return Rectangle2DRelation.ZEROINSIDE;
//			}else if(pointContain==1){
//				return Rectangle2DRelation.ONEINSIDE;
//			}else if(pointContain==2){
//				return Rectangle2DRelation.TWOINSIDE;
//			}
//			
//		}
//		return Rectangle2DRelation.OUTSIDE;
//		
//	}

	public List<Point2D> getPoint2D() {
		List<Point2D> result = new ArrayList<Point2D>();
		result.add(new Point2D.Double(getMinX(), getMinY()));
		result.add(new Point2D.Double(getMaxX(), getMinY()));
		result.add(new Point2D.Double(getMaxX(), getMaxY()));
		result.add(new Point2D.Double(getMinX(), getMaxY()));
		
		
		return result;
	} 
	
	public Point2D  getPoint2D (RectanglePoint e){
//		System.out.println(this.centerPoint.z()-this.zSize/2);
		if(e==RectanglePoint.TOPLEFT){
			return new Point2D.Double(getMinX() ,getMaxY());
		}else if (e== RectanglePoint.TOPRIGHT){
			return new Point2D.Double(getMaxX(), getMaxY());
		}else if(e==RectanglePoint.BOTTOMLEFT){
			return new Point2D.Double(position.getX(), position.getY());
		}else if (e== RectanglePoint.BOTTOMRIGHT){
			return new Point2D.Double(getMaxX(), getMinX());
		} 

		return null;
		
	}
	
	
	public List<XYRectangle> getLeftOverZeroPoint(XYRectangle xyRectangle){
		List<XYRectangle> result = new ArrayList<XYRectangle>();
//		Rectangle2D thisRectangle2D = this.toRectangle2D();
		Rectangle2D xyRectangle2D = xyRectangle.toRectangle2D();
		int leftOver1X = -1;
		int leftOver1Y = -1;
		int leftOverPosition1X = -1;
		int leftOverPosition1Y = -1;
		
		int leftOver2X = -1;
		int leftOver2Y = -1;
		int leftOverPosition2X = -1;
		int leftOverPosition2Y = -1;
		
		if((xyRectangle2D.contains(this.getPoint2D(RectanglePoint.TOPLEFT)) &&
				xyRectangle2D.contains(this.getPoint2D(RectanglePoint.TOPRIGHT)) )
				||(xyRectangle2D.contains(this.getPoint2D(RectanglePoint.BOTTOMLEFT)) &&
						xyRectangle2D.contains(this.getPoint2D(RectanglePoint.BOTTOMRIGHT)))){
			leftOver1X = this.getXSize();
			leftOverPosition1X = this.getMinX();
			if(xyRectangle2D.contains(this.getPoint2D(RectanglePoint.TOPLEFT)) &&
					xyRectangle2D.contains(this.getPoint2D(RectanglePoint.TOPRIGHT))){
				leftOver1Y = xyRectangle.getMinY()-this.getMinY();
				leftOverPosition1Y = this.getMinY();
				
			}else{
				leftOver1Y = this.getMaxY() - xyRectangle.getMaxY();
				leftOverPosition1Y =xyRectangle.getMaxY();
			}
		}else if((xyRectangle2D.contains(this.getPoint2D(RectanglePoint.TOPLEFT)) &&
				xyRectangle2D.contains(this.getPoint2D(RectanglePoint.BOTTOMLEFT)) )
				||(xyRectangle2D.contains(this.getPoint2D(RectanglePoint.TOPRIGHT)) &&
						xyRectangle2D.contains(this.getPoint2D(RectanglePoint.BOTTOMRIGHT)))){
			leftOver1Y = this.getYSize();
			leftOverPosition1Y = this.getMinY();
			if(xyRectangle2D.contains(this.getPoint2D(RectanglePoint.TOPLEFT)) &&
					xyRectangle2D.contains(this.getPoint2D(RectanglePoint.BOTTOMLEFT))){
				leftOver1X = this.getMaxX()- xyRectangle.getMaxX();
				leftOverPosition1X = xyRectangle.getMaxX();
				
			}else{
				leftOver1X = xyRectangle.getMinX() - this.getMinX();
				leftOverPosition1X = this.getMinX();
			}
		}else if(this.getMaxY() > xyRectangle.getMaxY()){
			leftOver1X = this.getXSize();
			leftOver1Y = xyRectangle.getMinY() - this.getMinY();
			leftOverPosition1X  = this.getMinX();
			leftOverPosition1Y  = this.getMinY();
			
			leftOver2X = this.getXSize();
			leftOver2Y = this.getMaxY() - xyRectangle.getMaxY();
			leftOverPosition2X = this.getMinX();
			leftOverPosition2Y = xyRectangle.getMaxY();
			
		}else{
			leftOver1X = xyRectangle.getMinX() - this.getMinX();
			leftOver1Y = this.getYSize();
			leftOverPosition1X  = this.getMinX();
			leftOverPosition1Y  = this.getMinY();
			
			leftOver2X = this.getMaxX() - xyRectangle.getMaxX();
			leftOver2Y = this.getYSize();
			leftOverPosition2X = xyRectangle.getMaxX();
			leftOverPosition2Y = this.getMinY();
		}
		
		if(leftOver1X>0 && leftOver1Y>0){
			result.add(new XYRectangle(new Point(leftOverPosition1X, leftOverPosition1Y, this.position.getZ()),
					leftOver1X,leftOver1Y, this.isPositiveFaced ));
			
		}
		
		if(leftOver2X>0 && leftOver2Y>0){
			result.add(new XYRectangle(new Point(leftOverPosition2X, leftOverPosition2Y, this.position.getZ()),
					leftOver2X,leftOver2Y, this.isPositiveFaced ));
			
		}
		
		
		return result;
	}
	public List<XYRectangle> getLeftOverTwoPoint(XYRectangle xyRectangle){
		List<XYRectangle> result = new ArrayList<XYRectangle>();
		Rectangle2D thisRectangle2D = this.toRectangle2D();
//		Rectangle2D xyRectangle2D = this.toRectangle2D();
		int leftOver1X = -1;
		int leftOver1Y = -1;
		
		int leftOver2X = -1;
		int leftOver2Y = -1;
		int leftOver2PositionX =-1;
		int leftOver2PositionY =-1;
		int leftOver2PositionZ =this.position.getZ();
		
		int leftOver3X = -1;
		int leftOver3Y = -1;
		int leftOver3PositionX =-1;
		int leftOver3PositionY =-1;
		int leftOver3PositionZ =this.position.getZ();
		
		Point leftOver1Position = this.position;
		if((thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.TOPLEFT)) && 
				thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.TOPRIGHT)))
				||  (thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.BOTTOMLEFT)) && 
						thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.BOTTOMRIGHT)))){
			leftOver1X = xyRectangle.getMinX() - this.getMinX();
			leftOver1Y = this.getYSize();
			
			leftOver2X = xyRectangle.getXSize();
			leftOver2PositionX = xyRectangle.getMinX();
			
			leftOver3X = this.getMaxX() - xyRectangle.getMaxX();
			leftOver3Y = this.getYSize();
			leftOver3PositionX = xyRectangle.getMaxX();
			
			if((thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.TOPLEFT)) && 
					thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.TOPRIGHT)))){
				leftOver2Y = this.getMaxY() - xyRectangle.getMaxY();
				leftOver2PositionY = xyRectangle.getMaxY();
				leftOver3PositionY = this.getMinY();
			}else{
				leftOver2Y = xyRectangle.getMinY() - this.getMinY();
				leftOver2PositionY = this.getMinY();
				leftOver3PositionY = this.getMinY();
			}
			
			
		}else if((thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.TOPLEFT)) && 
				thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.BOTTOMLEFT))
				||(thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.TOPRIGHT)) && 
						thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.BOTTOMRIGHT))))){
			
			leftOver1X = this.getXSize();
			leftOver1Y = xyRectangle.getMinY()- this.getMinY();
			
			leftOver2Y = xyRectangle.getYSize();
			leftOver2PositionY = xyRectangle.getMinY();

			leftOver3X = this.getXSize();
			leftOver3Y = this.getMaxY() -  xyRectangle.getMaxY();
			leftOver3PositionX = this.getMinX();
			leftOver3PositionY = xyRectangle.getMaxY();
			
			if((thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.TOPLEFT)) && 
					thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.BOTTOMLEFT)))){
				leftOver2PositionX = this.getMinX();
				leftOver2X =  xyRectangle.getMinX() - this.getMinX();
				
			}else{
				leftOver2PositionX = xyRectangle.getMaxX();
				leftOver2X =  this.getMinX()-xyRectangle.getMinX() ;
			}
			
		
		
		}
		
		if(leftOver1X >0  && leftOver1Y >0){
			
			result.add(new XYRectangle(leftOver1Position, leftOver1X, leftOver1Y, this.isPositiveFaced));
			
		}
		
		if(leftOver2X >0  && leftOver2Y >0){
			Point position = new Point(leftOver2PositionX, leftOver2PositionY, leftOver2PositionZ);
			result.add(new XYRectangle(position, leftOver2X, leftOver2Y, this.isPositiveFaced));
			
		}
		
		if(leftOver3X >0  && leftOver3Y >0){
			Point position = new Point(leftOver3PositionX, leftOver3PositionY, leftOver3PositionZ);
			result.add(new XYRectangle(position, leftOver3X, leftOver3Y, this.isPositiveFaced));
			
		}
		return result;
	}

	
	public  List<XYRectangle> getLeftOverOnePoint(XYRectangle xyRectangle){
		List<XYRectangle> result = new ArrayList<XYRectangle>();
		Rectangle2D thisRectangle2D = this.toRectangle2D();
//		Rectangle2D xyRectangle2D = this.toRectangle2D();
		Rectangle2D intersection = this.getOverlaped(xyRectangle).toRectangle2D();
		int leftOver1X  = (int)(thisRectangle2D.getWidth()  - intersection.getWidth());
		int leftOver1Y  = (int)(thisRectangle2D.getHeight());
		
		int leftOver2X  = (int)(intersection.getWidth());
		int leftOver2Y  = (int)(thisRectangle2D.getHeight() - intersection.getHeight());
		
		int leftOver1PositionX =-1;
		int leftOver1PositionY =-1;
		int leftOver1PositionZ =this.position.getZ();
		int leftOver2PositionX =-1;
		int leftOver2PositionY =-1;
		int leftOver2PositionZ =this.position.getZ();
		
		if(thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.TOPLEFT))){
			leftOver1PositionX = this.getMinX();
			leftOver1PositionY = this.getMinY();
			
			leftOver2PositionX = xyRectangle.getMinX();
			leftOver2PositionY = xyRectangle.getMaxY();
			
			
		}else if(thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.TOPRIGHT))){
			leftOver1PositionX = xyRectangle.getMaxX();
			leftOver1PositionY = this.getMinY();
			
			leftOver2PositionX = this.getMinX();
			leftOver2PositionY = xyRectangle.getMaxY();
		}else if(thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.BOTTOMLEFT))){
			leftOver1PositionX = this.getMinX();
			leftOver1PositionY = this.getMinY();
			
			leftOver2PositionX = xyRectangle.getMinX();
			leftOver2PositionY = this.getMinY();
		}else if(thisRectangle2D.contains(xyRectangle.getPoint2D(RectanglePoint.BOTTOMRIGHT))){
			leftOver1PositionX = xyRectangle.getMaxX();
			leftOver1PositionY = this.getMinY();
			
			leftOver2PositionX = this.getMinX();
			leftOver2PositionY = this.getMinY();
		}
		
		if(leftOver1X >0 && leftOver1Y >0 ){
			Point position = new Point(leftOver1PositionX, leftOver1PositionY, leftOver1PositionZ);
			result.add(new XYRectangle(position,leftOver1X,leftOver1Y,this.isPositiveFaced));
		}
		if(leftOver2X >0 && leftOver2Y >0 ){
			Point position = new Point(leftOver2PositionX, leftOver2PositionY, leftOver2PositionZ);
			result.add(new XYRectangle(position,leftOver2X,leftOver2Y,this.isPositiveFaced));
		}
		
		
		
		return result;
		
		
	}
	
	public  XYRectangle reverse(){
		this.isPositiveFaced = !this.isPositiveFaced;
		return this;
	}


}
